﻿// ===============================================================================
// XCI.WinForm.Platform 西安交通信息WinForm开发框架 2019 版权所有
// ===============================================================================
using System.Collections.Generic;
using System.Threading.Tasks;
using XCI.Core;
using XCI.Windows;
using XCI.Sys.Filter;
using XCI.Sys.Model;
using XCI.Helper;

namespace XCI.Sys.Service
{
    /// <summary>
    /// 系统模块服务
    /// </summary>
    public class SysModuleService
    {
        private const string RootUrl = "/api/sys/module";
        public static SysModuleService Instance { get; } = new SysModuleService();

        /// <summary>
        /// 新建菜单模块模型
        /// </summary>
        public async Task<SysModule> NewMenuAsync(string parentId)
        {
            return await Task.FromResult(new SysModule
            {
                IsWeb = false,
                IsWin = true,
                IsExpand = false,
                IsPublic = false,
                IsMenu = true,
                Status = true,
                ParentId = WinFormHelper.GetParentIdOrDefault(parentId)
            });
        }

        /// <summary>
        /// 新建权限模块模型
        /// </summary>
        public async Task<SysModule> NewPermissionAsync(string parentId)
        {
            return await Task.FromResult(new SysModule
            {
                IsWeb = false,
                IsWin = false,
                IsExpand = false,
                IsPublic = false,
                IsMenu = false,
                Status = true,
                ParentId = WinFormHelper.GetParentIdOrDefault(parentId)
            });
        }

        /// <summary>
        /// 复制对象
        /// </summary>
        /// <param name="id">源对象主键</param>
        public async Task CopyAsync(string id)
        {
            var model = await SelectByIdAsync(id);
            model.Id = null;
            model.Spell = null;
            model.Code += " - 复制";
            model.Name += " - 复制";
            await SaveAsync(true, model);
        }

        /// <summary>
        /// 检查模块编码是否存在
        /// </summary>
        /// <param name="code">模块编码</param>
        public async Task<bool> ExistByCodeAsync(string code)
        {
            return await App.Client.PostAsync<bool>($"{RootUrl}/existByCode", new { code });
        }

        /// <summary>
        /// 保存模块
        /// </summary>
        /// <param name="created">是否新增</param>
        /// <param name="model">模块对象</param>
        /// <returns>成功返回true</returns>
        public async Task<BoolResult> SaveAsync(bool created, SysModule model)
        {
            return await App.Client.PostAsBoolResultAsync($"{RootUrl}/{(created ? "insert" : "update")}", model);
        }

        /// <summary>
        /// 修改状态
        /// </summary>
        /// <param name="ids">主键字符串</param>
        /// <param name="status">启用状态[true-启用, false-禁用]</param>
        /// <returns>成功返回true</returns>
        public async Task UpdateStatusAsync(string ids, bool status)
        {
            await App.Client.PostAsync($"{RootUrl}/updateStatus", new { ids, status });
        }

        /// <summary>
        /// 修改模块公共状态
        /// </summary>
        /// <param name="ids">主键字符串</param>
        /// <param name="field">字段名称</param>
        /// <param name="status">公共状态</param>
        /// <returns>成功返回true</returns>
        public async Task UpdateField(string ids, string field, bool status)
        {
            await App.Client.PostAsync($"{RootUrl}/updateField", new { ids, field, value = status });
        }

        /// <summary>
        /// 保存节点拖拽数据
        /// </summary>
        /// <param name="keyValues">修改的数据集合</param>
        /// <returns>成功返回true</returns>
        public async Task UpdateDndAsync(List<PrimaryKeyValue> keyValues)
        {
            await App.Client.PostAsync($"{RootUrl}/updateNodeDrag", WinFormHelper.ToTreeNodeDnds(keyValues));
        }

        /// <summary>
        /// 删除模块
        /// </summary>
        /// <param name="ids">主键字符串</param>
        /// <returns>成功返回true</returns>
        public async Task DeleteAsync(string ids)
        {
            await App.Client.PostAsync($"{RootUrl}/delete", new { ids });
        }

        /// <summary>
        /// 根据主键获取模块对象
        /// </summary>
        /// <param name="id">模块主键</param>
        public async Task<SysModule> SelectByIdAsync(string id)
        {
            return await App.Client.PostAsync<SysModule>($"{RootUrl}/selectById", new { id });
        }

        /// <summary>
        /// 根据主键获取模块对象
        /// </summary>
        /// <param name="args">编辑参数</param>
        /// <param name="isMenu">是否菜单</param>
        public Task<SysModule> GetOrCreateAsync(EditFormArgs args, bool isMenu)
        {
            if (args == null || args.Created)
            {
                return isMenu ? NewMenuAsync(args?.ParentId) : NewPermissionAsync(args?.ParentId);
            }
            return SelectByIdAsync(args.Id);
        }

        /// <summary>
        /// 根据模块编码获取模块对象
        /// </summary>
        /// <param name="code">模块编码</param>
        /// <returns>成功返回模型对象</returns>
        public async Task<SysModule> SelectByCodeAsync(string code)
        {
            return await App.Client.PostAsync<SysModule>($"{RootUrl}/selectByCode", new { code });
        }

        /// <summary>
        /// 查询模块列表
        /// </summary>
        /// <param name="filter">过滤条件</param>
        public async Task<List<SysModule>> SelectListAsync(SysModuleFilter filter)
        {
            return await App.Client.PostAsync<List<SysModule>>($"{RootUrl}/selectList", filter);
        }

        /// <summary>
        /// 导出模块列表
        /// </summary>
        /// <param name="filePath">保存路径</param>
        /// <param name="filter">过滤条件</param>
        public async Task ExportAsync(string filePath, SysModuleFilter filter)
        {
            await App.Client.DownloadAsync($"{RootUrl}/export", filePath, filter);
        }

        /// <summary>
        /// 添加标准权限项
        /// </summary>
        /// <param name="parentModel">上级模型</param>
        public async Task SaveStandardPermissionAsync(SysModule parentModel)
        {
            var permissions = new List<KeyValue>
            {
                new KeyValue("查询", "select"),
                new KeyValue("新建", "insert"),
                new KeyValue("修改", "update"),
                new KeyValue("删除", "delete"),
                new KeyValue("导出", "export")
            };
            foreach (var item in permissions)
            {
                var module = await NewPermissionAsync(parentModel.Id);
                module.Name = $"{parentModel.Name}.{item.Key}";
                module.Code = $"{parentModel.Code}.{item.Value}";
                var has = await ExistByCodeAsync(module.Code);
                if (!has)
                {
                    await SaveAsync(true, module);
                }
            }
        }
    }
}